home *** CD-ROM | disk | FTP | other *** search
- /*
- * File: rcoexpr.r -- co_init, co_chng
- */
-
- #if COMPILER
- static continuation coexpr_fnc; /* function to call after switching stacks */
- #endif /* COMPILER */
-
- /*
- * co_init - use the contents of the refresh block to initialize the
- * co-expression.
- */
- novalue co_init(sblkp)
- struct b_coexpr *sblkp;
- {
- #ifndef Coexpr
- syserr("co_init() called, but co-expressions not implemented");
- #else /* Coexpr */
- register word *newsp;
- register struct b_refresh *rblkp;
- register dptr dp, dsp;
- int frame_size;
- word stack_strt;
- int na, nl, nt, i;
-
- /*
- * Get pointer to refresh block and get number of arguments and locals.
- */
- rblkp = (struct b_refresh *)BlkLoc(sblkp->freshblk);
- #if COMPILER
- na = rblkp->nargs;
- nl = rblkp->nlocals;
- nt = rblkp->ntemps;
- #else /* COMPILER */
- na = (rblkp->pfmkr).pf_nargs + 1;
- nl = (int)rblkp->numlocals;
- #endif /* COMPILER */
-
- #if COMPILER
- /*
- * The C stack must be aligned on the correct boundry. For upgrowing
- * stacks, the C stack starts after the initial procedure frame of
- * the co-expression block. For downgrowing stacks, the C stack starts
- * at the last word of the co-expression block.
- */
- #ifdef UpStack
- frame_size = sizeof(struct p_frame) + sizeof(struct descrip) * (nl + na +
- nt - 1) + rblkp->wrk_size;
- stack_strt = (word)((char *)&sblkp->pf + frame_size + StackAlign*WordSize);
- #else /* UpStack */
- stack_strt = (word)((char *)sblkp + stksize - WordSize);
- #endif /* UpStack */
- sblkp->cstate[0] = stack_strt & ~(WordSize * StackAlign - 1);
-
- #else /* COMPILER */
-
- /*
- * The interpreter stack starts at word after co-expression stack block.
- * C stack starts at end of stack region on machines with down-growing C
- * stacks and somewhere in the middle of the region.
- *
- * The C stack is aligned on a doubleword boundary. For upgrowing
- * stacks, the C stack starts in the middle of the stack portion
- * of the static block. For downgrowing stacks, the C stack starts
- * at the last word of the static block.
- */
-
- newsp = (word *)((char *)sblkp + sizeof(struct b_coexpr));
-
- #ifdef UpStack
- sblkp->cstate[0] =
- ((word)((char *)sblkp + (stksize - sizeof(*sblkp))/2)
- &~((word)WordSize*StackAlign-1));
- #else /* UpStack */
- sblkp->cstate[0] =
- ((word)((char *)sblkp + stksize - WordSize)
- &~((word)WordSize*StackAlign-1));
- #endif /* UpStack */
-
- #ifdef CoProcesses
- sblkp->cstate[1] = 0;
- #endif
-
- sblkp->es_argp = (dptr)newsp;
-
- #endif /* COMPILER */
-
- /*
- * Copy arguments onto new stack.
- */
- dp = rblkp->elems;
- #if COMPILER
- dsp = sblkp->pf.tend.d + nl; /* args follow locals */
- #else /* COMPILER */
- dsp = (dptr)newsp;
- #endif /* COMPILER */
- for (i = 1; i <= na; i++)
- *dsp++ = *dp++;
-
- /*
- * Set up state variables and initialize procedure frame.
- */
- #if COMPILER
- sblkp->es_pfp = &sblkp->pf;
- sblkp->es_tend = &sblkp->pf.tend;
- sblkp->es_argp = &sblkp->pf.tend.d[nl]; /* args are put after locals */
- sblkp->pf.old_pfp = NULL;
- sblkp->pf.rslt = NULL;
- sblkp->pf.succ_cont = NULL;
- sblkp->pf.tend.previous = NULL;
- sblkp->pf.tend.num = nl + na + nt;
- sblkp->es_actstk = NULL;
- #else /* COMPILER */
- *((struct pf_marker *)dsp) = rblkp->pfmkr;
- sblkp->es_pfp = (struct pf_marker *)dsp;
- sblkp->es_tend = NULL;
- dsp = (dptr)((word *)dsp + Vwsizeof(*pfp));
- sblkp->es_ipc.opnd = rblkp->ep;
- sblkp->es_gfp = 0;
- sblkp->es_efp = 0;
- sblkp->es_ilevel = 0;
- #endif /* COMPILER */
- sblkp->tvalloc = NULL;
-
- /*
- * Copy locals into the co-expression.
- */
- #if COMPILER
- dsp = sblkp->pf.tend.d;
- #endif /* COMPILER */
- for (i = 1; i <= nl; i++)
- *dsp++ = *dp++;
-
- #if COMPILER
- /*
- * Initialize temporary variables.
- */
- for (i = 1; i <= nt; i++)
- *dsp++ = nulldesc;
- #else /* COMPILER */
- /*
- * Push two null descriptors on the stack.
- */
- *dsp++ = nulldesc;
- *dsp++ = nulldesc;
-
- sblkp->es_sp = (word *)dsp - 1;
- #endif /* COMPILER */
-
- #endif /* Coexpr */
- }
-
- /*
- * co_chng - high-level co-expression context switch.
- */
- int co_chng(ncp, valloc, rsltloc, swtch_typ, first)
- struct b_coexpr *ncp;
- struct descrip *valloc; /* location of value being transmitted */
- struct descrip *rsltloc;/* location to put result */
- int swtch_typ; /* A_Coact, A_Coret, A_Cofail, or A_MTEvent */
- int first;
- {
- #ifndef Coexpr
- syserr("co_chng() called, but coexpressions not implemented");
- #else /* Coexpr */
- register struct b_coexpr *ccp;
- struct descrip rval;
- static int coexp_act; /* used to pass signal across activations */
- /* back to whomever activates, if they care */
-
- ccp = (struct b_coexpr *)BlkLoc(k_current);
-
- #if !COMPILER
- #ifdef EventMon
- switch(swtch_typ) {
- case A_Coact: EVValX(ncp,E_Coact); break;
- case A_Coret: EVValX(ncp,E_Coret); break;
- case A_Cofail: EVValX(ncp,E_Cofail); break;
- }
- #endif /* EventMon */
- #endif /* COMPILER */
-
- /*
- * Determine if we need to transmit a value.
- */
- if (ncp->tvalloc != NULL && valloc != NULL) {
-
- #if COMPILER
- deref(valloc, ncp->tvalloc);
- #else /* COMPILER */
- /*
- * Determine if we need to dereference transmited value.
- */
- rval = *valloc;
- if (Var(rval))
- retderef(&rval, &rval, (word *)ccp);
-
- *ncp->tvalloc = rval;
- #endif /* COMPILER */
-
- }
- ncp->tvalloc = NULL;
- ccp->tvalloc = rsltloc;
-
- /*
- * Save state of current co-expression.
- */
- ccp->es_pfp = pfp;
- ccp->es_argp = argp;
- ccp->es_tend = tend;
-
- #if !COMPILER
- ccp->es_efp = efp;
- ccp->es_gfp = gfp;
- ccp->es_ipc = ipc;
- ccp->es_sp = sp;
- ccp->es_ilevel = ilevel;
- #endif /* COMPILER */
-
- #if COMPILER
- if (line_info) {
- ccp->file_name = file_name;
- ccp->line_num = line_num;
- file_name = ncp->file_name;
- line_num = ncp->line_num;
- }
- #endif /* COMPILER */
-
- #if COMPILER
- if (debug_info)
- #endif /* COMPILER */
- if (k_trace)
- cotrace(ccp, ncp, swtch_typ, valloc);
-
- /*
- * Establish state for new co-expression.
- */
- pfp = ncp->es_pfp;
- argp = ncp->es_argp;
- tend = ncp->es_tend;
- #if !COMPILER
- efp = ncp->es_efp;
- gfp = ncp->es_gfp;
- ipc = ncp->es_ipc;
- sp = ncp->es_sp;
- ilevel = (int)ncp->es_ilevel;
- #endif /* COMPILER */
-
- #if !COMPILER
- #endif /* COMPILER */
-
- BlkLoc(k_current) = (union block *)ncp;
-
- #if COMPILER
- coexpr_fnc = ncp->fnc;
- #endif /* COMPILER */
-
- coexp_act = swtch_typ;
- coswitch(ccp->cstate, ncp->cstate,first);
- return coexp_act;
- #endif /* Coexpr */
- }
-
- #ifdef Coexpr
- /*
- * new_context - determine what function to call to execute the new
- * co-expression; this completes the context switch.
- */
- novalue new_context(fsig,cargp)
- int fsig;
- dptr cargp;
- {
- #if COMPILER
- (*coexpr_fnc)();
- #else /* COMPILER */
- interp(fsig, cargp);
- #endif /* COMPILER */
- }
- #endif /* Coexpr */
-